﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using mod = Wpf.Telemetry.Service.Model;
using System.Diagnostics;

namespace Wpf.Telemetry.Service.DataAccess.SQLServer
{
    public class SQLTelemetryRecorder : ITelemetryRecorder
    {
        private string connectionString;

        public SQLTelemetryRecorder(string connectionString)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                throw new ArgumentException("connection string cannot be null or empty");
            }

            this.connectionString = connectionString;
        }

        public void SaveFeatureUsage(mod.ApplicationInformation appInfo, mod.SystemInformation systemInfo, List<mod.FeatureUsage> featureUsage)
        {
            using (SQLServerTelemetryDataContext context = new SQLServerTelemetryDataContext(connectionString))
            {
                SystemInformation dbSysInfo = SaveSystemInfo(systemInfo, context);
                ApplicationInformation dbAppInfo = SaveApplicationInfo(appInfo, context);

                FeatureUsageRecord dbFeatUsg = new FeatureUsageRecord();
                dbFeatUsg.ApplicationInformation = dbAppInfo;
                dbFeatUsg.SystemInformation = dbSysInfo;
                dbFeatUsg.CreatedDate = DateTime.Now;
                dbFeatUsg.Id = Guid.NewGuid();
                context.FeatureUsageRecords.InsertOnSubmit(dbFeatUsg);

                foreach (mod.FeatureUsage usage in featureUsage)
                {
                    FeatureUsageInformation dbFeatInfo = new FeatureUsageInformation();
                    dbFeatInfo.CreatedDate = DateTime.Now;
                    dbFeatInfo.FeatureName = usage.FeatureName;
                    dbFeatInfo.FeatureUsageRecord = dbFeatUsg;
                    dbFeatInfo.Id = Guid.NewGuid();
                    dbFeatInfo.UsageCount = usage.UsageCount;
                    context.FeatureUsageInformations.InsertOnSubmit(dbFeatInfo);
                }

                context.SubmitChanges();
            }
        }

        public void SaveException(mod.SystemInformation systemInfo, mod.ExceptionInformation exceptionInfo)
        {
            using (SQLServerTelemetryDataContext context = new SQLServerTelemetryDataContext(connectionString))
            {
                SystemInformation dbSysInfo = SaveSystemInfo(systemInfo, context);

                ExceptionInformation dbExInfo = new ExceptionInformation();
                dbExInfo.CallStack = exceptionInfo.CallStack;
                dbExInfo.CreatedDate = DateTime.Now;
                dbExInfo.EmailAddress = exceptionInfo.EmailAddress;
                dbExInfo.ErrorDescription = exceptionInfo.ErrorDescriptionFromUser;
                dbExInfo.ExceptionName = exceptionInfo.ExceptionName;
                dbExInfo.Id = Guid.NewGuid();
                dbExInfo.Message = exceptionInfo.Message;
                dbExInfo.SystemInformation = dbSysInfo;

                context.ExceptionInformations.InsertOnSubmit(dbExInfo);
                context.SubmitChanges();
            }
        }

        private static ApplicationInformation SaveApplicationInfo(mod.ApplicationInformation appInfo, SQLServerTelemetryDataContext context)
        {
            ApplicationInformation dbAppInfo = new ApplicationInformation();
            dbAppInfo.Id = Guid.NewGuid();
            dbAppInfo.CreatedDate = DateTime.Now;
            dbAppInfo.UserSessionId = appInfo.UserSession;
            dbAppInfo.Version = appInfo.Version;
            dbAppInfo.WorkingSet = appInfo.WorkingSet;
            context.ApplicationInformations.InsertOnSubmit(dbAppInfo);
            return dbAppInfo;
        }

        private static SystemInformation SaveSystemInfo(mod.SystemInformation systemInfo, SQLServerTelemetryDataContext context)
        {
            SystemInformation dbSysInfo = new SystemInformation();
            dbSysInfo.Id = Guid.NewGuid();
            dbSysInfo.CLRVersion = systemInfo.CLRVersion;
            dbSysInfo.CreatedDate = DateTime.Now;
            dbSysInfo.DomainHash = systemInfo.DomainNameHash;
            dbSysInfo.IsSlowMachine = systemInfo.IsSlowMachine;
            dbSysInfo.IsTabletPc = systemInfo.IsTabletPc;
            dbSysInfo.OperatingSystem = systemInfo.OperatingSystem;
            dbSysInfo.PhysicalMemory = systemInfo.PhysicalMemory;
            dbSysInfo.ProcessorArchitecture = systemInfo.ProcessorArchitecture;
            dbSysInfo.ProcessorCount = systemInfo.ProcessorCount;
            dbSysInfo.RenderCapabilityTier = systemInfo.RenderCapabilityTier;
            dbSysInfo.ScreenHeight = systemInfo.ScreenHeight;
            dbSysInfo.ScreenWidth = systemInfo.ScreenWidth;
            dbSysInfo.UserNameHash = systemInfo.UserNameHash;
            dbSysInfo.MachineNameHash = systemInfo.ComputerNameHash;
            context.SystemInformations.InsertOnSubmit(dbSysInfo);
            return dbSysInfo;
        }

    }
}
